//
// Contians C Debug code
/*******************************************************************
//		*** COPYRIGHT NOTICE ****
//
//	Copyright 2003. David Maisonave (david@axter.com)
//	
//	This code is free for use under the following conditions:
//
//		You may not claim authorship of this code.
//		You may not sell or distrubute this code without author's permission.
//		You can use this code for your applications as you see fit, but this code may not be sold in any form
//		to others for use in their applications.
//		This copyright notice may not be removed.
//
//
//  No guarantees or warranties are expressed or implied. 
//	This code may contain bugs.
*******************************************************************/
//  Please let me know of any bugs, bug fixes, or enhancements made to this code.
//  If you have ideas for this, and/or tips or admonitions, I would be glad to hear them.
//
//////////////////////////////////////////////////////////////////////


#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#include <ctype.h>
#include <memory.h> 
#include <fcntl.h>
#include <time.h>
#include <io.h>

#include "debuglog.h"  //Need this for deblock_data and block_data

DEBUGLOG_CODE_INIT_;

//By defining the following macro, function tracing can be turned off without having to recompile the entire code
//#define DEBUGLOG_TRACEALLFUNCCALLS_OFF
//To turn on function tracing, the above directive has to be commented out,
//and the DEBUGLOG_TRACEALLFUNCCALLS_ON has to be defined in the debuglog.h header file

//To add the timestamp to the debuglog, uncomment the following line
//#define DEBUG__MODE_TIMESTAMP 

void DosBeep__(int usFrequency, int usDuration)
{
	DosBeep(usFrequency, usDuration);
}

//#define DEBUGLOG_ALL_OUTPUT_TO_1FILE

static const char far QuoteAndEndLine[3][3] = {"'\n", "\n","'\n"};
static const char far DebugFileName[][16] = {
        "C:\\DebugLog.txt",
#ifdef DEBUGLOG_ALL_OUTPUT_TO_1FILE
        "c:\\DebugLog.txt", // Alternate debug file
        "c:\\DebugLog.txt"  // Alternate debug file
#else
        "c:\\DebugLg2.txt", // Alternate debug file
        "c:\\DebugLg3.txt"  // Alternate debug file
#endif //DEBUGLOG_ALL_OUTPUT_TO_1FILE
        };
static const char far TraceText[]				= " LOGIC TRACE ";
static const char far TraceErrorLogMsg[]		= " TRACE ERROR!";
static const char far FuncTraceErrorLogMsg[]	= " **Function Trace**";

int Debug_strlen(const char far * Src)
{
	return strlen(Src);
}

static FILE  far * DbgFileDesc[sizeof(DebugFileName)/sizeof(DebugFileName[0])] = {NULL};
static int far Initialize_DbgFileDesc_Null = 0;

#ifdef DEBUG__MODE_TIMESTAMP
static const char far FormatForType[3][20] = {"(%5.5i) [%s] :-&gt; '", "(%5.5i) [%s] :-&gt; ", "(%5.5i) [%s] :-&gt; '"};
static const char far TimeForamt[] = "%d%H%M%S";
#else
static const char far FormatForType[3][16] = {"(%5.5i) :-&gt; '", "(%5.5i) :-&gt; ","(%5.5i) :-&gt; '"};
#endif //DEBUG__MODE_TIMESTAMP

static const char far WriteOpenMode[] = "w";
static const char far HexHeaderFormat[] = "Hex Dump %i Byte(s):\n\t\t";


void DebugOut_Impl(const char far * gf_Filename, int gf_LineNo, int gf_LogType, const char far * DebugData, int Size, int OutInHex)
{
	const char* DebugMsg = NULL;
	int SizeOfDebugMsg = 0;
#ifdef DEBUG__MODE_TIMESTAMP
	char timeStamp[99];
 	time_t now = time((time_t*)NULL);
#endif //DEBUG__MODE_TIMESTAMP

	int Row, TmpNum;
#ifdef DEBUGLOG_ALL_OUTPUT_TO_1FILE
	gf_LogType = 0;
#endif //DEBUGLOG_ALL_OUTPUT_TO_1FILE
	if (!Initialize_DbgFileDesc_Null)
	{
		Initialize_DbgFileDesc_Null = 1;
		memset(DbgFileDesc, 0, sizeof(DbgFileDesc));
	}

	if (gf_LogType &gt;= sizeof(DbgFileDesc)/sizeof(DbgFileDesc[0]) ||
		gf_LogType &lt; 0)
	{
		gf_LogType = 0;
	}
	
//    if (DEBUG_GETFILEPROFILE_ID(999) &amp;&amp; DbgFileDesc[gf_LogType] != NULL)
//	{
//		fclose(DbgFileDesc[gf_LogType]);
//		DbgFileDesc[gf_LogType] = NULL;
//	}  

	if (DbgFileDesc[gf_LogType] == NULL)
    {
	    DbgFileDesc[gf_LogType] = fopen(DebugFileName[gf_LogType], WriteOpenMode);
		
		if (DbgFileDesc[gf_LogType] == NULL)
		{
			DEBUG_HORN;
			DEBUG_BEEP_BEEP;
			DEBUG_HORN;
			DEBUG_BEEP_BEEP;
			DEBUG_HORN;
			return;
		}
    }

	fwrite(gf_Filename, 1, strlen(gf_Filename), DbgFileDesc[gf_LogType]);
#ifdef DEBUG__MODE_TIMESTAMP
	strftime(timeStamp, sizeof(timeStamp),
				TimeForamt,localtime(&amp;now));
	fprintf(DbgFileDesc[gf_LogType], FormatForType[OutInHex], gf_LineNo, timeStamp);
#else
	fprintf(DbgFileDesc[gf_LogType], FormatForType[OutInHex], gf_LineNo);
#endif //DEBUG__MODE_TIMESTAMP
	
	if (DebugData == NULL || Size &lt; 0)
	{
		switch(Size)
		{
		case -1:
			DebugMsg		= TraceText;
			SizeOfDebugMsg	= sizeof(TraceText);
			break;
		case -2:
			DebugMsg		= TraceErrorLogMsg;
			SizeOfDebugMsg	= sizeof(TraceErrorLogMsg);
			break;
		case -3:
			DebugMsg		= FuncTraceErrorLogMsg;
			SizeOfDebugMsg	= sizeof(FuncTraceErrorLogMsg);
			break;
		}
		fwrite(DebugMsg, 1, SizeOfDebugMsg-1,DbgFileDesc[gf_LogType]);
	}
	else
	{
		if (OutInHex)
		{
			Row = 0;
			fprintf(DbgFileDesc[gf_LogType], HexHeaderFormat, Size);
			while(Size &gt; 0)
			{
				TmpNum = (unsigned char)DebugData[0];
				if (OutInHex == 1)
				{
					fprintf(DbgFileDesc[gf_LogType], "%2.2X ", TmpNum);
				}
				else
				{
					if (isprint(TmpNum))
					{
						fwrite(&amp;DebugData[0], 1, 1, DbgFileDesc[gf_LogType]);
					}
					else
					{
						fprintf(DbgFileDesc[gf_LogType], "|0x%2.2X|", TmpNum);
					}
				}
				++DebugData;
				--Size;
				if (OutInHex == 1)
				{
					++Row;
					if (Row == 16)
					{
						fprintf(DbgFileDesc[gf_LogType], "\n\t\t");
						Row = 0;
					}
				}
			}
		}
		else
		{
			fwrite(DebugData, 1, Size, DbgFileDesc[gf_LogType]);
		}
	}

	fwrite(QuoteAndEndLine[OutInHex], 1, strlen(QuoteAndEndLine[OutInHex]), DbgFileDesc[gf_LogType]);
	fflush(DbgFileDesc[gf_LogType]);
}


void DebugOut(const char far * gf_Filename, int gf_LineNo, int gf_LogType, const char far * DebugData, int Size)
{
	DebugOut_Impl(gf_Filename, gf_LineNo, gf_LogType, DebugData, Size, 0);
}

int DebugOutFuncTrace(const char far * gf_Filename, int gf_LineNo, int gf_LogType, const char far * DebugData, int Size)
{
#ifndef DEBUGLOG_TRACEALLFUNCCALLS_OFF
	DebugOut_Impl(gf_Filename, gf_LineNo, gf_LogType, DebugData, -3, 0);
#endif //!DEBUGLOG_TRACEALLFUNCCALLS_OFF
	return 0;
}

void DebugOut_textonly(const char far * gf_Filename, int gf_LineNo, int gf_LogType, const char far * DebugData, int Size)
{
	DebugOut_Impl(gf_Filename, gf_LineNo, gf_LogType, DebugData, Size, 2);
}

static char StrNumber[16];

void DebugOut_Int(const char far * gf_Filename, int gf_LineNo, int gf_LogType, int DebugData)
{
	StrNumber[0] = 0;
	sprintf(StrNumber, "%i", DebugData);
	DebugOut(gf_Filename, gf_LineNo, gf_LogType, StrNumber, strlen(StrNumber));
}

void DebugOut_Float(const char far * gf_Filename, int gf_LineNo, int gf_LogType, float DebugData)
{
	StrNumber[0] = 0;
	sprintf(StrNumber, "%f", DebugData);
	DebugOut(gf_Filename, gf_LineNo, gf_LogType, StrNumber, strlen(StrNumber));
}

void DebugOut_Hex(const char far * gf_Filename, int gf_LineNo, int gf_LogType, const unsigned char *DebugData, int Len)
{
	DebugOut_Impl(gf_Filename, gf_LineNo, gf_LogType, (const char*)DebugData, Len, 1);
}
/*
	The Function below a allows the debug version of the application
	to take a different path if and ID value is set in the debugenv.txt file
	This file should have the following format:
intuch.c:32=1
intuch.c:11=1
vgm_send.c:88=1
inmac.c:546=1
inmac.c:423=0
intuch.c:900=1
insodr.c:321=0
insodr.c:555=1
globalnamefoo:322=1
foofoo:99=1

	The file should be limit to a few ID's and all file-names/global-names MUST be lower case
*/
static const char far DebugEnvFileName[] = "c:\\debugenv.txt";
int  DebugGetFileProfile(const char far * gf_Filename, int gf_LineNo)
{
	int ReturnValue = 0;
	char LineBuf[999];
	char KeyWord[999];
	int LenKW;
	static int NotifyIfFailToOpen = 1;
	FILE * file = _fsopen(DebugEnvFileName, "rt", SH_DENYNO);
	if (!file) 
	{
		if (NotifyIfFailToOpen)
		{
			NotifyIfFailToOpen = 0;
			DosBeep__(600, 300);DosBeep__(600, 100);DosBeep__(600, 300);
		}
		return ReturnValue;
	}
	sprintf(KeyWord, "%s:%i=", gf_Filename, gf_LineNo);
	strlwr(KeyWord);
	LenKW = strlen(KeyWord);
	while( fgets( LineBuf, sizeof(LineBuf), file ) != NULL )
	{
		if (!strncmp(KeyWord, LineBuf, LenKW))
		{
			ReturnValue = atoi(&amp;LineBuf[LenKW]);
			break;
		}
	}
	fclose(file);
	return ReturnValue;
}</io.h></time.h></fcntl.h></memory.h></ctype.h></stdlib.h></limits.h></stdio.h>